<!--
* @description svg地图
* @author zywu
* @date 2021/12/07 20:44:36
!-->
<template>
  <div class="svg-map" @dblclick="dblclick">
    <div class="svg-map__inner" :style="imgStyle">
      <!-- 平台视图显示单位安全评分 -->
      <template v-if="isPlatView">
        <div class="svg-map-marker" :class="'org'+n.orgId" v-for="n in markList" :key="n.orgId" :style="n.style" @click="goUnitHome(n)">
          <div class="svg-map-marker__text">{{n.safetyScore}}</div>
        </div>
      </template>

      <!-- 单位视图显示警情数、消防设施 -->
      <template v-else>
        <div v-for="(n,i) in alarmList" :key="i" class="svg-map-marker svg-map-marker-alarm" :style="getAlarmStyle(n)" @click="goDeviceList(n)">
          <div class="svg-map-marker__text">{{n.count}}</div>
        </div>
      </template>

      <div class="svg-map__embed">
        <!-- <embed :src="svgUrl" width="100%" height="100%" type="image/png" pluginspage="http://www.adobe.com/svg/viewer/install/" /> -->
        <img :src="svgUrl" width="100%" height="100%" />
      </div>

      <div ref="mask" class="svg-map__mask" @mousedown="handleMouseDown"></div>
    </div>
  </div>
</template>

<script>
import { on, off } from 'element-ui/src/utils/dom'
import { rafThrottle, isFirefox } from 'element-ui/src/utils/util'
import { mapState } from 'vuex'
import { getOrgAlarmCount } from '@/api/hiddenDanger'

let platformCode = localStorage.getItem('ilinkBs_platformCode')
const Mode = {
  CONTAIN: {
    name: 'contain',
    icon: 'el-icon-full-screen',
  },
  ORIGINAL: {
    name: 'original',
    icon: 'el-icon-c-scale-to-original',
  },
}

const mousewheelEventName = isFirefox() ? 'DOMMouseScroll' : 'mousewheel'

let fbsPosition = {}

const getDefaultTransform = function () {
  return {
    scale: 1,
    deg: 0,
    offsetX: 0,
    offsetY: 0,
    enableTransition: false,
  }
}

export default {
  components: {},

  data() {
    return {
      mode: Mode.CONTAIN,
      transform: getDefaultTransform(),
      queue: {
        0: true,
      },
      markList: [],
      platformCode,
      alarmStyle: {
        top: '46%',
        left: '48%',
        backgroundImage:
          'url(/ilink-fe-config/zhxf-bs/' + platformCode + '/map/popup.png)',
      },
      alarmList: [],
    }
  },

  computed: {
    imgStyle() {
      const { scale, deg, offsetX, offsetY, enableTransition } = this.transform
      const style = {
        transform: `scale(${scale}) rotate(${deg}deg)`,
        transition: enableTransition ? 'transform .3s' : '',
        'margin-left': `${offsetX}px`,
        'margin-top': `${offsetY}px`,
      }
      if (this.mode === Mode.CONTAIN) {
        style.maxWidth = style.maxHeight = '100%'
      }
      return style
    },
    ...mapState(['currentOrgId', 'userInfo']),
    mapId() {
      // return this.currentOrgId || this.userInfo.org.id
      return 'map'
    },
    svgUrl() {
      return (
        '/ilink-fe-config/zhxf-bs/' +
        platformCode +
        '/map/' +
        this.mapId +
        '.png'
      )
    },
    isPlatView() {
      return this.userInfo.isMuilUnitUser && !this.currentOrgId
    },
  },

  watch: {
    '$store.state.unitGroup'(val) {
      this.updateAllMarks(val)
    },
    // mapId() {
    //   this.getMapJSON()
    // },
    currentOrgId(val) {
      if (fbsPosition) {
        this.getOrgAlarmCount()
      } else {
        this.getFbsJSON()
      }
    },
  },

  created() {
    this.getFbsJSON()
    this.getMapJSON()
    window.ZHXF_RESET_SVG_MAP = this.dblclick
    window.ZHXF_FOCUS_UNIT_MAP = this.focusUnitMap
    window.ZHXF_ALARM_NUM = this.getOrgAlarmCount
  },

  mounted() {
    this.deviceSupportInstall()
  },

  beforeDestroy() {
    this.alarmList = []
    this.deviceSupportUninstall()
  },

  methods: {
    goDeviceList(param) {
      this.$Ctl.enterDetail('EquipmentList', {
        name: '',
        fbsId: param.fbsId,
        status: param.status,
        orgId: param.orgId,
      })
    },
    getAlarmStyle(n) {
      let style = fbsPosition[n.fbsId] || {}
      style.display = style.top ? 'flex' : 'none'
      style.backgroundImage = `url(${
        this.GLOBAL.mapMarkJsonData[51].fmapIconNew[n.status]
      })`
      return style
    },
    getFbsJSON() {
      fetch('/ilink-fe-config/zhxf-bs/' + platformCode + '/map/fbs' + '.json')
        .then((res) => res.json())
        .then((res) => {
          if (res) {
            fbsPosition = res
            this.getOrgAlarmCount()
          }
        })
        .catch(() => {})
    },
    getOrgAlarmCount() {
      if (this.isPlatView) return
      let orgId = this.currentOrgId || localStorage.getItem('ilinkBs_orgIds')
      getOrgAlarmCount({
        orgId,
      }).then((res) => {
        this.alarmList = res.data
          .map((n, i) => {
            let obj = JSON.parse(n)
            return obj
          })
          .filter((n) => {
            return n.count > 0
          })
      })
    },
    focusUnitMap(orgId) {
      let transform = this.unitPosition[orgId].transform
      this.transform = {
        scale: transform.scale,
        deg: 0,
        offsetX: transform.left,
        offsetY: transform.top,
        enableTransition: false,
      }
    },
    getMapJSON() {
      fetch(
        '/ilink-fe-config/zhxf-bs/' +
          platformCode +
          '/map/' +
          this.mapId +
          '.json'
      )
        .then((res) => res.json())
        .then((res) => {
          if (res) {
            this.unitPosition = res
            this.updateAllMarks(this.$store.state.unitGroup)
          }
        })
        .catch(() => {
          this.markList = []
        })
    },
    goUnitHome(n) {
      this.$Ctl.enterSingleHome({
        orgId: n.orgId,
      })
    },
    updateAllMarks(val) {
      if (this.unitPosition) {
        this.markList = val.map((n) => {
          n.style = (this.unitPosition[n.orgId] || {}).mark || {}
          n.style.backgroundImage =
            'url(' + this.getIconByScore(n.safetyScore) + ')'
          n.style.display = n.style.top ? 'flex' : 'none'
          return n
        })
      }
    },
    // 根据分数计算颜色
    getIconByScore(val) {
      let index = 2
      if (val < 80) index = 0
      if (val >= 80 && val < 90) index = 1
      return this.GLOBAL.mapMarkJsonData[34].fmapIcon[index]
    },
    dblclick() {
      if (this.isPlatView) {
        this.transform = getDefaultTransform()
      } else {
        this.focusUnitMap(this.currentOrgId)
      }
    },
    deviceSupportInstall() {
      this._mouseWheelHandler = rafThrottle((e) => {
        const delta = e.wheelDelta ? e.wheelDelta : -e.detail
        if (delta > 0) {
          this.handleActions('zoomIn', {
            zoomRate: 0.075,
            enableTransition: false,
          })
        } else {
          this.handleActions('zoomOut', {
            zoomRate: 0.075,
            enableTransition: false,
          })
        }
      })
      on(document, 'keydown', this._keyDownHandler)
      // on(document, mousewheelEventName, this._mouseWheelHandler)
      on(this.$refs.mask, mousewheelEventName, this._mouseWheelHandler)
    },
    deviceSupportUninstall() {
      off(document, 'keydown', this._keyDownHandler)
      // off(document, mousewheelEventName, this._mouseWheelHandler)
      off(this.$refs.mask, mousewheelEventName, this._mouseWheelHandler)
      this._keyDownHandler = null
      this._mouseWheelHandler = null
    },
    handleMouseDown(e) {
      const { offsetX, offsetY } = this.transform
      const startX = e.pageX
      const startY = e.pageY
      this._dragHandler = rafThrottle((ev) => {
        this.transform.offsetX = offsetX + ev.pageX - startX
        this.transform.offsetY = offsetY + ev.pageY - startY
      })
      on(document, 'mousemove', this._dragHandler)
      on(document, 'mouseup', (ev) => {
        off(document, 'mousemove', this._dragHandler)
      })

      e.preventDefault()
    },
    handleActions(action, options = {}) {
      const { zoomRate, enableTransition } = {
        zoomRate: 0.2,
        rotateDeg: 90,
        enableTransition: true,
        ...options,
      }
      const { transform } = this
      switch (action) {
        case 'zoomOut':
          if (transform.scale > 0.2) {
            transform.scale = parseFloat(
              (transform.scale - zoomRate).toFixed(3)
            )
          }
          break
        case 'zoomIn':
          transform.scale = parseFloat((transform.scale + zoomRate).toFixed(3))
          break
      }
      transform.enableTransition = enableTransition
    },
  },
}
</script>
<style lang='scss'>
.svg-map {
  position: absolute;
  height: 100%;
  width: 100%;
  background: rgba(17, 34, 90, 1);
  z-index: 1;
  &-device {
    position: absolute;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    &__top {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      animation: animateFloat 2s infinite linear;
    }
    &__name {
      zoom: 0.4;
    }
    img {
      width: 30px;
    }
    &__bottom {
      transform: scale(0.5);
    }
    &.device1 {
      color: #3c83f6;
    }
    &.device2 {
      color: #4fbfe9;
    }
    &.device3 {
      color: #fd5e5e;
    }
    &.device4 {
      color: #47cfad;
    }
  }
  &__embed {
    width: 100%;
    height: 100%;
  }
  &__img {
    object-fit: cover;
  }
  &-marker {
    display: flex;
    justify-content: center;
    position: absolute;
    z-index: 1;
    width: 100px;
    height: 100px;
    line-height: 90px;
    background-position: center;
    background-repeat: no-repeat;
    background-size: 100% 100%;
    font-size: 24px;
    cursor: pointer;
    &-alarm {
      width: 70px;
      height: 70px;
      line-height: 70px;
      animation: animateFloat 2s infinite linear;
      font-size: 30px;
    }
    &:hover {
      z-index: 2;
    }
    &__text {
      margin-top: 1px;
      color: #fff;
    }
  }
  &__inner {
    position: relative;
    width: 100%;
    height: 100%;
    display: flex;
    flex-wrap: wrap;
  }
  &__mask {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
  }
  @keyframes animateFloat {
    0% {
      transform: translateY(0);
    }
    50% {
      transform: translateY(-3px);
    }
    100% {
      transform: translateY(0);
    }
  }
}
</style>
